home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1999 September (IDG) / Sep99.iso / Shareware World / Utilities / Text Processing / Alpha / Tcl / Modes / javaMode.tcl < prev    next >
Encoding:
Text File  |  1999-03-21  |  10.2 KB  |  316 lines  |  [TEXT/ALFA]

  1. # (install)
  2.  
  3. alpha::mode Java 1.09 javaMenu {*.java *.j} {
  4.     javaMenu electricBraces electricSemicolon electricReturn
  5. } {
  6.     addMenu javaMenu "•140" Java
  7. }
  8.  
  9. array set javacompilerAppSignatures {
  10.     Suncompiler Javc
  11. }
  12. array set javacompilerAppScripts {
  13.     Suncompiler {
  14.     {sendOpenEvent -n $quotedSig $filename}
  15.     }
  16. }
  17.  
  18. # required for use of C++::correctIndentation
  19. newPref f useFasterButWorseIndentation 0 Java
  20. newPref v indentComments "code 0" Java "" indentationTypes varitem
  21. newPref v indentC++Comments "code 0" Java "" indentationTypes varitem
  22.  
  23. newPref    f elecColon {1} Java
  24. newPref    v leftFillColumn {3} Java
  25. newPref    v prefixString {//} Java 
  26. newPref    f wordWrap {0} Java
  27. newPref    v funcExpr {^[^ \t\(#\r/@].*\(.*\)$} Java
  28. newPref    v parseExpr {\b([_:\w]+)\s*\(} Java
  29. newPref v wordBreak {[\w_]+} Java
  30. newPref v wordBreakPreface {[^_\w]} Java
  31. newPref    f autoMark    0 Java
  32. # To synchronise Alpha's value for your java class path with the current
  33. # value in your system environment each time Alpha starts up, click this 
  34. # box||To let Alpha maintain its own value for your classpath independent
  35. # of the systemwide value, click this box.
  36. newPref    f classPathSynchroniseWithEnv    1 Java
  37. # Your Java class path.
  38. newPref v classSearchPath "" Java
  39. newPref    v stringColor    green Java
  40. newPref    v commentColor    red     Java
  41. newPref    v keywordColor    blue Java
  42. newPref v funcColor yellow Java
  43. newPref f includeMenu 1 Java
  44. newPref variable showJavacompilerLog 1 Java "" \
  45.   [list "Never" "Only after error" "Always"] index
  46.  
  47. regModeKeywords     -e {//} -b {/*} {*/}    -c $JavamodeVars(commentColor) \
  48.          -f $JavamodeVars(funcColor) -k $JavamodeVars(keywordColor) \
  49.          -s $JavamodeVars(stringColor) Java {
  50.     abstract boolean break byte byvalue case catch char class const 
  51.     continue default do double else extends false final finally float for 
  52.     goto if implements import instanceof int interface long native new 
  53.     null package private protected public return short static super switch 
  54.     synchronized this throw throws transient true try void while future 
  55.     generic inner outer operator rest var volatile
  56. }
  57. regModeKeywords -a -k color_9 Java { Object String }
  58.  
  59. proc javaMenu {} {}
  60.  
  61. if {$JavamodeVars(classPathSynchroniseWithEnv)} {
  62.     if {[info exists env(CLASSPATH)]} {
  63.     set JavamodeVars(classSearchPath) [split $env(CLASSPATH) ";"]
  64.     }
  65. }
  66.  
  67. ## 
  68.  # -------------------------------------------------------------------------
  69.  # 
  70.  # "menu::buildjavaMenu" --
  71.  # 
  72.  #  Use a build proc so we can add things on the fly.
  73.  # -------------------------------------------------------------------------
  74.  ##
  75. proc Java::buildMenu {} {
  76.     global javaMenu
  77.     set ma {
  78.     "/S<U<OswitchToCompiler"
  79.     "(-"
  80.     "/K<U<OcompileFile"
  81.     "(-"
  82.     "/V<U<OviewApplet"
  83.     "//<BnewJavadocComment"
  84.     }
  85.     return [list build $ma Java::MenuProc "" $javaMenu]
  86. }
  87. menu::buildProc javaMenu Java::buildMenu
  88.  
  89. set Java::commentCharacters(Paragraph) [list "/**" " */" " * "]
  90.  
  91. # If this package exists, add the headers menu
  92. if {[alpha::package exists searchPaths]} {
  93.     menu::buildProc javaSearchPath {mode::rebuildSearchPathMenu javaSearchPath}
  94.     menu::insert javaMenu submenu end javaSearchPath
  95. }
  96.  
  97. menu::buildSome javaMenu
  98.  
  99. proc Java::MenuProc {menu item} {
  100.     eval Java::$item
  101. }
  102.  
  103. proc Java::electricLeft {args} {
  104.     uplevel 1 C++::electricLeft $args
  105. }
  106.  
  107. proc Java::correctIndentation {args} {
  108.     uplevel 1 C++::correctIndentation $args
  109. }
  110. proc Java::indentLine {args} {
  111.     uplevel 1 C++::indentLine $args
  112. }
  113.  
  114. proc Java::newJavadocComment {} {
  115.     elec::Insertion "/**\r * •comment body•\r */\r••"
  116. }
  117.  
  118. # Launches Java Compiler
  119. proc Java::switchToCompiler {} {
  120.     global javacompilerSig
  121.     app::launchAnyOfThese Javc javacompilerSig "Please locate the Java compiler:"
  122.     switchTo '$javacompilerSig'
  123. }
  124.  
  125. # Sends the window to the compiler.
  126. proc Java::compileFile {} {
  127.     global showJavacompilerLog classSearchPath
  128.     set path [stripNameCount [win::Current]]
  129.  
  130.     if {[winDirty]} {
  131.     case [askyesno -c "Save '[file tail $path]'?"] in {
  132.         "yes" {
  133.         save
  134.         # Get path again, in case it was Untitled before.
  135.         set path [stripNameCount [win::Current]]
  136.         }
  137.         "no" {
  138.         if {![file exists $path]} {
  139.             alertnote "Can't send window to compiler."
  140.             return
  141.         }
  142.         }
  143.         "cancel" {return}
  144.     }
  145.     }
  146.     app::runScript javacompiler "Java compiler" \
  147.       $path 0 $showJavacompilerLog "-classpath [join $classSearchPath {;}]"
  148. }
  149.  
  150. # Opens a HTML file corresponding to a java file in the Applet Viewer.
  151. # If there is a file some_applet.html in the same folder as some_applet.java
  152. # it is sent. Otherwise the user is asked to select a HTML file.
  153. # This file is remembered throughout this session with Alpha.
  154. proc Java::viewApplet {} {
  155.     global javaAppletFile javaviewerSig
  156.     set name [stripNameCount [win::Current]]
  157.     set dir [file dirname $name]
  158.     set root [file rootname [file tail $name]]
  159.     set path [file join $dir $root.html]
  160.     if {[info exists javaAppletFile($name)] && [file exists $javaAppletFile($name)]} {
  161.     set path $javaAppletFile($name)
  162.     } elseif {![file exists $path]} {
  163.     set path [getfile "Please locate HTML file for applet."]
  164.     set javaAppletFile($name) $path
  165.     }
  166.     app::launchAnyOfThese [list AppV WARZ] javaviewerSig "Please locate the Applet viewer:"
  167.     sendOpenEvent noReply '$javaviewerSig' $path
  168.     switchTo '$javaviewerSig'
  169. }
  170.  
  171. proc Java::MarkFile {} {
  172.     Java::MarkFile2 1
  173. }
  174.  
  175. proc Java::parseFuncs {} {
  176.     Java::MarkFile2 0
  177. }
  178.  
  179.  
  180. # My version of    Java::MarkFile. First revision, April 1996.
  181. # Jim Menard, jimm@io.com
  182. # Improved by Vince: both start and end position of embedded classes are
  183. # stored, so if we order methods/sub-classes randomly, we still mark 
  184. # things properly.
  185. proc Java::MarkFile2 {marking} {
  186.     # Sorry, but globals are a lot easier than using "upvar" in subroutines
  187.     global markArray
  188.     global classInfo
  189.     
  190.     catch {unset markArray}
  191.     set classInfo ""
  192.     
  193.     # Look for class definitions first
  194.     set markExpr "^\[ \t\]*(\[A-Za-z_\]\[A-Za-z0-9_\]*\[ \t\]+)*class\[ \t\]+\[A-Za-z_\]\[A-Za-z0-9_\]*\[ \t\r\](\[A-Za-z_\]\[A-Za-z0-9_.\]*\[ \t\]+)*\{"
  195.     set wordExpr "class\[ \t\]+(\[A-Za-z_\]\[A-Za-z0-9_\]*)"
  196.     set commands {
  197.     set markArray([concat $word "class"]) $markPos
  198.     # Remember mark    position and name separately so    we can call
  199.     # Java::getClassFromPos() later.
  200.     lappend    classInfo [list $word $markPos $endPos]
  201.     }
  202.     Java::searchAndDestroy $markExpr $wordExpr $commands 0
  203.     
  204.     # The following regular expression is overly restrictive. After the open
  205.     # paren, I disallow semicolons. That avoids finding lines like
  206.     # throw new FooException(arg);
  207.     # which is good, but unfortunately also avoids finding lines like
  208.     # public int foo(arg) // comment with semi;
  209.     #
  210.     # It doesn't find constructors without a "public", "private", or other phrase
  211.     # before the method name since it requires at least one word before the
  212.     # method name. They are special-cased below. I did that so function calls,
  213.     # "if" statements, and the like wouldn't be found.
  214.     set markExpr "^\[ \t\]*(\[A-Za-z_\]\[A-Za-z0-9_\]*(\\\[\\])*\[ \t\]+)+\[A-Za-z_\]\[A-Za-z0-9_\]*\[ \t\r\]*\\(\[^;\]+$"
  215.     set wordExpr "(\[A-Za-z_\]\[A-Za-z0-9_\]*)\[ \t\]*\\("
  216.     set commands {
  217.     if {$className == $word} {
  218.         set markArray([concat $className "constructor"]) $markPos
  219.     } else {
  220.         set markArray(${className}::$word) $markPos
  221.     }
  222.     }
  223.     Java::searchAndDestroy $markExpr $wordExpr $commands 1
  224.     
  225.     # One more time; let's go back for constructors    with no    modifiers.
  226.     set markExpr "^\[ \t\]*\[A-Za-z\]\[A-Za-z0-9_\]*\[ \t\r\]*\\(\[^;\]+$"
  227.     set wordExpr "(\[A-Za-z\]\[A-Za-z0-9_\]*)\[ \t\]*\\("
  228.     set commands {
  229.     if {$className == $word} {
  230.         set markArray([concat $className "constructor"]) [lineStart [expr $start - 1]]
  231.     }
  232.     }
  233.     Java::searchAndDestroy $markExpr $wordExpr $commands 1
  234.     
  235.     if {[info exists markArray]} {
  236.     foreach    f [lsort -ignore [array    names markArray]] {
  237.         set next [nextLineStart $markArray($f)]
  238.         
  239.         if {[regexp {.*(::if)$} $f] == 0} {
  240.         if {[string length $f] > 35} { 
  241.             set ff "[string range $f 0 31]..." 
  242.         } else {
  243.             set ff $f
  244.         }
  245.         if {$marking} {
  246.             setNamedMark "$ff" "$markArray($f)" $next $next
  247.         } else {
  248.             lappend parse $ff $next
  249.         }
  250.         }
  251.     }
  252.     }
  253.     if {!$marking} {return $parse}
  254. }
  255.  
  256. # Start    at top of file and find    text that matches markExpr. Clean it up    and
  257. # use wordExpr to find the word    we want. Execute commands.
  258. proc Java::searchAndDestroy {markExpr wordExpr commands needClassName} {
  259.     global markArray
  260.     global classInfo
  261.     if {!$needClassName} {
  262.     set getEnd 0
  263.     }
  264.     
  265.     set pos [minPos]
  266.     while {![catch {search -s -f 1 -r 1 -m 0 -i 0 -- "$markExpr" $pos} res]} {
  267.     set start [lindex $res 0]
  268.     set end    [pos::math [lindex $res 1] + 1]
  269.     if {[pos::compare $end > [maxPos]]} {
  270.         set end [maxPos]
  271.     }
  272.     set thistext [getText $start $end]
  273.     if {$needClassName} {
  274.         set className [Java::getClassFromPos $start $classInfo]
  275.     }
  276.     # regexp doesn't like carriage returns or tabs
  277.     regsub -all "\[\n\r\t\]" $thistext " " thistext
  278.     # If the open paren was    the last character on the line,
  279.     # the selected text included the last carriage return as well.
  280.     # Trim this off    now that it is changed into a space.
  281.     set thistext [string trimright $thistext]
  282.     if {[regexp -- $wordExpr $thistext dummy word]} {
  283.         set markPos [lineStart [pos::math $start - 1]]
  284.         if {[info exists getEnd]} {
  285.         if {$getEnd} {
  286.             set endPos [lindex [search -s -f 1 -m 0 -i 0 -- "\{" $markPos] 1]
  287.             set endPos [matchIt "\{" $endPos]
  288.         } else {
  289.             # little efficiency thing: the first class we find, we know
  290.             # extends to the end of the file, so we don't bother doing
  291.             # its 'matchIt' because it is very time-consuming.
  292.             set endPos [maxPos]
  293.             set getEnd 1
  294.         }
  295.         }
  296.         eval $commands
  297.     }
  298.     set pos    $end
  299.     }
  300. }
  301.  
  302. # Given    a file position, find the class    definition in which it resides.
  303. # There's got to be an easier way than passing two separate lists. 
  304. # I tried fooling
  305. # around with markArray(), but don't know Tcl well enough to use it instead.
  306. proc Java::getClassFromPos {pos classInfo} {
  307.     set nClasses [llength $classInfo]
  308.     for {set i [expr {$nClasses - 1}]} {$i >= 0} {incr i -1} {
  309.     set range [lindex $classInfo $i]
  310.     if {[pos::compare [lindex $range 1] <= $pos] && [pos::compare [lindex $range 2] >= $pos]} {
  311.         return [lindex $range 0]
  312.     }
  313.     }
  314.     return ""
  315. }
  316.